package com.uatair.common.mqtt.uploader;

import cn.hutool.core.util.RandomUtil;
import com.uatair.common.core.redis.RedisCache;
import com.uatair.common.mqtt.domain.OsdData;
import com.uatair.common.mqtt.domain.WuHuFlightData;
import com.uatair.common.mqtt.domain.dto.ApiUploadResponse;
import com.uatair.common.mqtt.util.AESUtil;
import com.uatair.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class WuHuTaskUploader {
    private static final String FLIGHT_KEY_PREFIX = "uav:flight:";
    private static final long FLIGHT_TTL_MINUTES = 3; // 3分钟TTL

    // Redis中存储的字段名常量
    private static final String ORDER_ID_FIELD = "orderId";
    private static final String FLIGHT_TIME_FIELD = "flightTime";
    private static final String LAST_UPDATE_FIELD = "lastUpdate";
    private static final String START_TIME_FIELD = "startTime";

    private final RedisCache redisCache;

    public WuHuTaskUploader(RedisCache redisCache) {
        this.redisCache = redisCache;
    }

    public void assembleFlightData(OsdData uavInfo, String sn) {
        if (uavInfo.getGs() > 0 && uavInfo.getHeight() > 0) {
            WuHuFlightData flightData = new WuHuFlightData();
//            flightData.setOrderID(AESUtil.formatOrderId(uavInfo.getOrder_id()));
            flightData.setManufactureID("914403003116581250");
            flightData.setUasID("UAS-DEFAULT");
            flightData.setTimeStamp(DateUtils.dateTimeNow());
            flightData.setFlightTime(uavInfo.getFly_time());
            flightData.setCoordinate("2");
            flightData.setLongitude((long) (uavInfo.getLongitude() * 1e7));
            flightData.setLatitude((long) (uavInfo.getLatitude() * 1e7));
            flightData.setHeight((long) (uavInfo.getHeight() * 100));
            flightData.setAltitude((long) (uavInfo.getAltitude() * 100));
            flightData.setSpeed((long) (uavInfo.getGs() * 10));
            flightData.setCourse(String.valueOf((long) (uavInfo.getHeading() * 10)));
            flightData.setUavType(uavInfo.getUas_model());
            if (uavInfo.getUas_model().contains("Q20Y")) {
                flightData.setLoadWeight(40.00);
                flightData.setIndustryAttribute("物流配送");
            } else {
                flightData.setLoadWeight(20.25);
                flightData.setIndustryAttribute("巡检");
            }
            processFlightData(flightData, sn);
        }
    }

    /**
     * 处理飞行数据（自动计算间隔时间）
     * @param flightData 飞行数据DTO
     */
    public void processFlightData(WuHuFlightData flightData, String sn) {
        String redisKey = FLIGHT_KEY_PREFIX + sn;
        long currentTime = System.currentTimeMillis();

        // 从Redis获取完整飞行记录
        Map<String, Object> flightRecord = redisCache.getCacheMap(redisKey);

        if (flightRecord != null && !flightRecord.isEmpty()) {
            // 已有记录 - 计算实际间隔时间
            long lastUpdateTime = Long.parseLong(flightRecord.get(LAST_UPDATE_FIELD).toString());
            long actualInterval = (currentTime - lastUpdateTime) / 1000; // 转换为秒

            // 更新飞行时间（最小间隔1秒，防止异常值）
            long currentFlightTime = Long.parseLong(flightRecord.get(FLIGHT_TIME_FIELD).toString());
            long newFlightTime = currentFlightTime + Math.max(actualInterval, 1);

            // 更新飞行数据
            flightData.setFlightTime(newFlightTime);
            flightData.setOrderID(flightRecord.get(ORDER_ID_FIELD).toString());

            // 更新Redis记录
            flightRecord.put(FLIGHT_TIME_FIELD, newFlightTime);
            flightRecord.put(LAST_UPDATE_FIELD, currentTime);
            redisCache.setCacheMap(redisKey, flightRecord);
        } else {
            // 新记录 - 初始化
            String newOrderId = generateOrderId(sn);
            flightData.setOrderID(newOrderId);
            flightData.setFlightTime(0); // 初始飞行时间为0

            // 存储到Redis
            Map<String, Object> newRecord = new HashMap<>();
            newRecord.put(ORDER_ID_FIELD, newOrderId);
            newRecord.put(FLIGHT_TIME_FIELD, 0L);
            newRecord.put(START_TIME_FIELD, currentTime);
            newRecord.put(LAST_UPDATE_FIELD, currentTime);

            redisCache.setCacheMap(redisKey, newRecord);
        }
        // 上报数据
        reportFlightData(flightData);

        // 刷新TTL（每次访问都重置过期时间）
        redisCache.expire(redisKey, FLIGHT_TTL_MINUTES, TimeUnit.MINUTES);
    }

    /**
     * 生成飞行记录编号
     * 格式: SN-YYYYMMDD-随机码(6位)
     */
    private String generateOrderId(String sn) {
        String datePart = DateUtils.parseDateToStr("yyyyMMdd", new Date());
        String randomPart = RandomUtil.randomString(8);
        return sn + "-" + datePart + "-" + randomPart;
    }

    // 配置参数
    private static final String BASE_URL = "http://60.169.172.225:8889/prod-api/";
    private static final String USERNAME = "18827542526";
    private static final String PASSWORD = "LianHe_20250801";
    private static final String KEY = "0b38add640d84349b861cd4f6918bf40";
    private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi6C1moPNpMamiui7rmKisnWQvv2nwIEL8GOeRvYPBHNJnRs7bidFvlDTHP2V8TMlpo7T2kJNPFOOsuFJYwURXX2prWNYDpKZbzrjLOmaq+MjGalsAxdZegtNDSbsZ7QRShYWLEppoypF5xdybZLrDAE4Z6uTPaPBwCn1FxxMZq95M6yCZTNjGw84SoR67EOSvTrg7/LaxKbb47SrGOhF7U0X6Fw/Nwa0EvVAdfbep4iScyLzPlk6IeoCBUs90e4v+s0C0YJLgEvpK8EG+XnO9DCWMUigBxGQ4MsfeITrjbiaVnClntQeVcu9gOiwEoHGwggDHHcB4xHhROKyVF/4twIDAQAB";
    private static String apiToken;

    public void reportFlightData(WuHuFlightData flightData) {
        try {
            // 构建请求体
            String body = buildRequestBody(flightData);
            log.info("reportFlightDataWuHu调用数据：{}",body);
            JSONObject requestBody = new JSONObject(body);
            Response post = getPostWithAuth(requestBody, BASE_URL + "externreceive/openApi/v1/uav/heartbeat");
            String responseBody = post.body().string();
            JSONObject responseJson = new JSONObject(responseBody);
            log.info("reportFlightDataWuHu返回数据: {}", responseJson);
            if (post.code() != 200)
                getToken();
            if ("500".equals(responseJson.get("code").toString()))
                getToken();
        } catch (Exception e) {
            log.error("上报飞行数据异常: {}", e.getMessage());
            e.printStackTrace();
        }
    }

    private String buildRequestBody(WuHuFlightData flightData) {
        return String.format(
                "{\"timestamp\": %d, \"data\": [%s]}",
                System.currentTimeMillis(),
                flightData.toJson()
        );
    }

    private static void getToken() throws Exception {
        // RSA加密参数
        String encryptedKey = AESUtil.rsaEncrypt(KEY, PUBLIC_KEY);
        String encryptedUsername = AESUtil.rsaEncrypt(USERNAME, PUBLIC_KEY);
        String encryptedPassword = AESUtil.rsaEncrypt(PASSWORD, PUBLIC_KEY);

        // 构建请求体
        String requestBody = String.format(
                "{\"key\":\"%s\",\"username\":\"%s\",\"password\":\"%s\",\"usertype\":\"1\"}",
                encryptedKey, encryptedUsername, encryptedPassword);

        // 设置请求URL
        URL url = new URL(BASE_URL + "auth/api/v1/token");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        // 发送请求
        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }

        // 获取响应
        int responseCode = conn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                // 解析token
                String jsonResponse = response.toString();
                JSONObject responseJson = new JSONObject(jsonResponse);
                if ("200".equals(responseJson.get("code").toString()))
                    apiToken = responseJson.get("token").toString();
//                int tokenStart = jsonResponse.indexOf("\"token\":\"") + 9;
//                int tokenEnd = jsonResponse.indexOf("\"", tokenStart);
//                log.info("更新token:{}",apiToken);
            }
        } else {
            throw new RuntimeException("获取Token失败，HTTP错误码: " + responseCode);
        }
    }

    public static Response getPostWithAuth(JSONObject requestBody, String url) throws Exception {
        OkHttpClient client = new OkHttpClient();

        RequestBody body = RequestBody.create(
                okhttp3.MediaType.parse("application/json; charset=utf-8"),
                requestBody.toString()
        );
        if (apiToken==null)
            getToken();
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", apiToken)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .post(body)
                .build();

        return client.newCall(request).execute();
    }
}
